/*	
	
	Copyright (c) 2007-2009 Ryan Christiansen
	
	This software is provided 'as-is', without any express or implied
	warranty. In no event will the authors be held liable for any damages
	arising from the use of this software.
	
	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:
	
	1. The origin of this software must not be misrepresented; you must not
	claim that you wrote the original software. If you use this software
	in a product, an acknowledgment in the product documentation would be
	appreciated but is not required.
	
	2. Altered source versions must be plainly marked as such, and must not be
	misrepresented as being the original software.
	
	3. This notice may not be removed or altered from any source
	distribution.
	
*/
package funit.framework
{
	import funit.MessageValidator;
	
	import mx.collections.ArrayCollection;
	
	[TestFixture]
	public class CollectionAssertTests extends MessageValidator
	{
		
		
		public function CollectionAssertTests()
		{
			
		}
		
		
		[Test]
		public function itemsOfType() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem("z");
			
			CollectionAssert.allItemsAreInstancesOf(collection, String);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function itemsOfTypeFailure() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem(new Object());
			
			expectedMessage =
				"  Expected: all items instance of <String>" + MessageString.NewLine +
				"  But was:  [ \"x\", \"y\", <Object> ]" + MessageString.NewLine;
			
			CollectionAssert.allItemsAreInstancesOf(collection, String);
		}
		
		[Test]
		public function itemsNotNull() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem("z");
			
			CollectionAssert.allItemsAreNotNull(collection);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function itemsNotNullFailure() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem(null);
			collection.addItem("z");
			
			expectedMessage =
				"  Expected: all items not null" + MessageString.NewLine +
				"  But was:  [ \"x\", null, \"z\" ]" + MessageString.NewLine;
			
			CollectionAssert.allItemsAreNotNull(collection);
		}
		
		[Test]
		public function itemsUniqueObjects() : void
		{
			CollectionAssert.allItemsAreUnique(
				new ArrayCollection( [new Object(), new Object(), new Object()] )
			);
		}
		
		[Test]
		public function itemsUniqueStrings() : void
		{
			CollectionAssert.allItemsAreUnique(
				new ArrayCollection( ["x", "y", "z"] )
			);
		}
		
		[Test]
		public function itemsUniqueHandlesNull() : void
		{
			CollectionAssert.allItemsAreUnique(
				new ArrayCollection( ["x", "y", null, "z"] )
			);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function itemsUniqueFailure() : void
		{
			expectedMessage =
				"  Expected: all items unique" + MessageString.NewLine +
				"  But was:  [ \"x\", \"y\", \"x\" ]" + MessageString.NewLine;
			
			CollectionAssert.allItemsAreUnique( new ArrayCollection( ["x", "y", "x"] ) );
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function itemsUniqueFailureOnTwoNulls() : void
		{
			expectedMessage =
				"  Expected: all items unique" + MessageString.NewLine +
				"  But was:  [ \"x\", null, \"y\", null, \"z\" ]" + MessageString.NewLine;
			
			CollectionAssert.allItemsAreUnique( new ArrayCollection( ["x", null, "y", null, "z"] ) );
		}
		
		[Test]
		public function contains() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem("z");
			
			CollectionAssert.contains(collection, "x");
		}
		
		[Test]
		public function containsNull() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem(1);
			collection.addItem(2);
			collection.addItem(3);
			collection.addItem(null);
			collection.addItem(4);
			collection.addItem(5);
			
			CollectionAssert.contains(collection, null);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function containsFailure() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem("z");
			
			expectedMessage =
				"  Expected: collection containing \"a\"" + MessageString.NewLine +
				"  But was:  [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine;
			
			CollectionAssert.contains(collection, "a");
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function containsFailureOnEmpty() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			expectedMessage =
				"  Expected: collection containing \"x\"" + MessageString.NewLine +
				"  But was:  <empty>" + MessageString.NewLine;
			
			CollectionAssert.contains(collection, "x");
		}
		
		[Test]
		public function doesNotContain() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem("z");
			
			CollectionAssert.doesNotContain(collection, "a");
		}
		
		[Test]
		public function doesNotContainOnEmpty() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			CollectionAssert.doesNotContain(collection, "x");
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function doesNotContainFailure() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem("z");
			
			expectedMessage =
				"  Expected: collection not containing \"y\"" + MessageString.NewLine +
				"  But was:  [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine;
			
			CollectionAssert.doesNotContain(collection, "y");
		}
		
		[Test]
		public function isEmpty() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			CollectionAssert.isEmpty( collection, "Failed on empty ArrayCollection" );
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function isEmptyFailure() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem("z");
			
			expectedMessage =
				"  Expected: <empty>" + MessageString.NewLine +
				"  But was:  [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine;
			
			CollectionAssert.isEmpty(collection);
		}
		
		[Test]
		public function isNotEmpty() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			collection.addItem("x");
			collection.addItem("y");
			collection.addItem("z");
			
			CollectionAssert.isNotEmpty( collection, "Failed on ArrayCollection" );
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function isNotEmptyFailure() : void
		{
			var collection:ArrayCollection = new ArrayCollection();
			
			expectedMessage =
				"  Expected: not <empty>" + MessageString.NewLine +
				"  But was:  <empty>" + MessageString.NewLine;
			
			CollectionAssert.isNotEmpty(collection);
		}
		
		[Test]
		public function areEqual() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set1.addItem("x");
			set1.addItem("y");
			set1.addItem("z");
			
			set2.addItem("x");
			set2.addItem("y");
			set2.addItem("z");
			
			CollectionAssert.areEqual(set1, set2);
		}
		
		[Test]
		public function areEqualHandlesNull() : void
		{
			var set1:ArrayCollection = new ArrayCollection( [ null, null, null ] );
			var set2:ArrayCollection = new ArrayCollection( [ null, null, null ] );
			
			CollectionAssert.areEqual(set1, set2);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function areEqualFailure() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set1.addItem("x");
			set1.addItem("y");
			set1.addItem("z");
			
			set2.addItem("x");
			set2.addItem("y");
			set2.addItem("a");
			
			expectedMessage =
				"  Expected and actual are both <mx.collections::ArrayCollection> with 3 elements" + MessageString.NewLine +
				"  Values differ at index [2]" + MessageString.NewLine +
				"  String lengths are both 1. Strings differ at index 0." + MessageString.NewLine +
				"  Expected: \"z\"" + MessageString.NewLine +
				"  But was:  \"a\"" + MessageString.NewLine +
				"  -----------^" + MessageString.NewLine;
			
			CollectionAssert.areEqual(set1, set2);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function areEqualFailureOnLength() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set1.addItem("x");
			set1.addItem("y");
			set1.addItem("z");
			
			set2.addItem("x");
			set2.addItem("y");
			set2.addItem("z");
			set2.addItem("a");
			
			expectedMessage =
				"  Expected is <mx.collections::ArrayCollection> with 3 elements, actual is <mx.collections::ArrayCollection> with 4 elements" + MessageString.NewLine +
				"  Values differ at index [3]" + MessageString.NewLine +
				"  Extra:    [ \"a\" ]" + MessageString.NewLine;
			
			CollectionAssert.areEqual(set1, set2);
		}
		
		[Test]
		public function areNotEqual() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set1.addItem("x");
			set1.addItem("y");
			set1.addItem("z");
			
			set2.addItem("x");
			set2.addItem("y");
			set2.addItem("a");
			
			CollectionAssert.areNotEqual(set1, set2);
		}
		
		[Test]
		public function areNotEqualHandlesNull() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set2.addItem(null);
			set2.addItem("y");
			set2.addItem(null);
			
			set2.addItem("x");
			set2.addItem("y");
			set2.addItem("z");
			
			CollectionAssert.areNotEqual(set1, set2);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function areNotEqualFailure() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set1.addItem("x");
			set1.addItem("y");
			set1.addItem("z");
			
			set2.addItem("x");
			set2.addItem("y");
			set2.addItem("z");
			
			expectedMessage =
				"  Expected: not [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine +
				"  But was:  [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine;
			
			CollectionAssert.areNotEqual(set1, set2);
		}
		
		[Test]
		public function areEquivalent() : void
		{
			var set1:ArrayCollection = new ArrayCollection( ["x", "y", "z"] );
			var set2:ArrayCollection = new ArrayCollection( ["z", "y", "x"] );
			
			CollectionAssert.areEquivalent(set1, set2);
		}
		
		[Test]
		public function areEquivalentHandlesNull() : void
		{
			var set1:ArrayCollection = new ArrayCollection( [null, "x", null, "z"] );
			var set2:ArrayCollection = new ArrayCollection( ["z", null, "x", null] );
			
			CollectionAssert.areEquivalent(set1, set2);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function areEquivalentFailure() : void
		{
			var set1:ArrayCollection = new ArrayCollection( ["x", "y", "z"] );
			var set2:ArrayCollection = new ArrayCollection( ["x", "y", "x"] );
			
			expectedMessage =
				"  Expected: equivalent to [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine +
				"  But was:  [ \"x\", \"y\", \"x\" ]" + MessageString.NewLine;
			
			CollectionAssert.areEquivalent(set1, set2);
		}
		
		[Test]
		public function areNotEquivalent() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set1.addItem("x");
			set1.addItem("y");
			set1.addItem("z");
			
			set2.addItem("x");
			set2.addItem("y");
			set2.addItem("x");
			
			CollectionAssert.areNotEquivalent(set1, set2);
		}
		
		[Test]
		public function areNotEquivalentHandlesNull() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set1.addItem("x");
			set1.addItem(null);
			set1.addItem("z");
			
			set2.addItem("x");
			set2.addItem(null);
			set2.addItem("x");
			
			CollectionAssert.areNotEquivalent(set1, set2);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function areNotEquivalentFailure() : void
		{
			var set1:ArrayCollection = new ArrayCollection();
			var set2:ArrayCollection = new ArrayCollection();
			
			set1.addItem("x");
			set1.addItem("y");
			set1.addItem("z");
			
			set2.addItem("x");
			set2.addItem("z");
			set2.addItem("y");
			
			expectedMessage =
				"  Expected: not equivalent to [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine +
				"  But was:  [ \"x\", \"z\", \"y\" ]" + MessageString.NewLine;
			
			CollectionAssert.areNotEquivalent(set1, set2);
		}
		
		[Test]
		public function isSubsetOf() : void
		{
			var subset:ArrayCollection   = new ArrayCollection();
			var superset:ArrayCollection = new ArrayCollection();
			
			subset.addItem("y");
			subset.addItem("z");
			
			superset.addItem("x");
			superset.addItem("y");
			superset.addItem("z");
			
			CollectionAssert.isSubsetOf(subset, superset);
		}
		
		[Test]
		public function isSubsetOfHandlesNull() : void
		{
			var subset:ArrayCollection   = new ArrayCollection();
			var superset:ArrayCollection = new ArrayCollection();
			
			subset.addItem(null);
			subset.addItem("z");
			
			superset.addItem("x");
			superset.addItem(null);
			superset.addItem("z");
			
			CollectionAssert.isSubsetOf(subset, superset);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function isSubsetOfFailure() : void
		{
			var subset:ArrayCollection   = new ArrayCollection();
			var superset:ArrayCollection = new ArrayCollection();
			
			subset.addItem("x");
			subset.addItem("y");
			subset.addItem("z");
			
			superset.addItem("y");
			superset.addItem("z");
			superset.addItem("a");
			
			expectedMessage =
				"  Expected: subset of [ \"y\", \"z\", \"a\" ]" + MessageString.NewLine +
				"  But was:  [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine;
			
			CollectionAssert.isSubsetOf(subset, superset);
		}
		
		[Test]
		public function isNotSubsetOf() : void
		{
			var subset:ArrayCollection   = new ArrayCollection();
			var superset:ArrayCollection = new ArrayCollection();
			
			subset.addItem("x");
			subset.addItem("y");
			subset.addItem("z");
			
			superset.addItem("y");
			superset.addItem("z");
			superset.addItem("a");
			
			CollectionAssert.isNotSubsetOf(subset, superset);
		}
		
		[Test]
		public function isNotSubsetOfHandlesNull() : void
		{
			var subset:ArrayCollection   = new ArrayCollection();
			var superset:ArrayCollection = new ArrayCollection();
			
			subset.addItem("x");
			subset.addItem(null);
			subset.addItem("z");
			
			superset.addItem(null);
			superset.addItem("z");
			superset.addItem("a");
			
			CollectionAssert.isNotSubsetOf(subset, superset);
		}
		
		[Test]
		[ExpectedError("funit.errors::AssertionError")]
		public function isNotSubsetOfFailure() : void
		{
			var subset:ArrayCollection   = new ArrayCollection();
			var superset:ArrayCollection = new ArrayCollection();
			
			subset.addItem("y");
			subset.addItem("z");
			
			superset.addItem("x");
			superset.addItem("y");
			superset.addItem("z");
			
			expectedMessage =
				"  Expected: not subset of [ \"x\", \"y\", \"z\" ]" + MessageString.NewLine +
				"  But was:  [ \"y\", \"z\" ]" + MessageString.NewLine;
			
			CollectionAssert.isNotSubsetOf(subset, superset);
		}
		
	}
	
}